﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ForgeCraftServer.Events;
using System.Diagnostics;
using LibMinecraft.Server;
using LibMinecraft.Model;
using System.Threading;
using ForgeCraftServer.Plugins;

namespace ForgeCraftServer
{
    /// <summary>
    /// ForgeCraft runs the LibMinecraft server and provides
    /// access to most functionality.  It cannot be instantiated -
    /// all of the methods and properties are static.
    /// </summary>
    public sealed class ForgeCraft
    {
        public static Plugin_Manager PLUGIN_MANAGER;

        private ForgeCraft()
        {
        }

        #region Events

        /// <summary>
        /// Called when ForgeCraft requests a string to be logged.
        /// </summary>
        public static event EventHandler<LogEventArgs> OnLog;

        #endregion

        #region Properties

        /// <summary>
        /// The XmlSettings instance for this server
        /// </summary>
        public static XmlSettings Settings { get; set; }
        /// <summary>
        /// The network manager for this server
        /// </summary>
        public static MultiplayerServer Server { get; set; }
        /// <summary>
        /// Details about the server, such as Message of the Day
        /// and port.
        /// </summary>
        public static MinecraftServer MinecraftServer { get; set; }

        /// <summary>
        /// This is the server version
        /// </summary>
        public static Version Version { get { return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; } }

        #endregion

        #region Public Methods

        /// <summary>
        /// Writes the specified message to the appropriate log
        /// </summary>
        public static void Log(string Message)
        {
            try
            {
                string prepend = "[" + DateTime.Now.ToString("HH:mm:ss") + "] ";
                try
                {
                    if (Settings.GetBoolean("server.debugenabled"))
                    {
                        // In debug mode, stick the calling class and method into the log
                        StackTrace trace = new StackTrace();
                        prepend += trace.GetFrame(1).GetMethod().DeclaringType.Name + "." + trace.GetFrame(1).GetMethod().Name + ": ";
                    }
                }
                catch { }
                if (OnLog != null)
                    OnLog(Server, new LogEventArgs(prepend + Message));
            }
            catch { }
        }

        public static void Initialize()
        {
            MinecraftServer = new MinecraftServer();

            // Load default settings
            Settings = new XmlSettings();

            PLUGIN_MANAGER = new Plugin_Manager();
            PLUGIN_MANAGER.LoadAll(true);

            Settings["server.port"] = "25565";
            Settings["server.motd"] = "A ForgeCraft Server";
            Settings["server.maxplayers"] = "25";
            Settings["server.difficulty"] = "normal";
            Settings["server.gamemode"] = "creative";
            Settings["server.onlinemode"] = "true";
#if DEBUG
            Settings["server.debugenabled"] = "true";
            Settings["server.onlinemode"] = "false";
#endif
        }

        public static void LoadSettings(string Directory)
        {
            Settings.Load(Directory, true);
        }

        /// <summary>
        /// Runs the ForgeCraft server
        /// </summary>
        public static void Start()
        {
            MinecraftServer = new MinecraftServer();
            MinecraftServer.Port = Settings.GetInt("server.port");
            MinecraftServer.OnlineMode = Settings.GetBoolean("server.onlinemode");
            MinecraftServer.MaxPlayers = Settings.GetInt("server.maxplayers");
            MinecraftServer.MotD = Settings["server.motd"];

            Server = new MultiplayerServer(MinecraftServer);

            // Event handlers
            Server.OnChat += new EventHandler<ChatEventArgs>(Server_OnChat);
            Server.OnPlayerJoin += new EventHandler<PlayerEventArgs>(Server_OnPlayerJoin);
            Server.OnPlayerLeave += new EventHandler<PlayerEventArgs>(Server_OnPlayerLeave);

            Server.Start();
        }

        #endregion

        #region Event Handlers

        static void Server_OnPlayerLeave(object sender, PlayerEventArgs e)
        {
            Server.SendChat("§e" + e.Player.PlayerEntity.Name + " left the game.");
            Log("§e" + e.Player.PlayerEntity.Name + " left the game.");
        }

        static void Server_OnPlayerJoin(object sender, PlayerEventArgs e)
        {
            Server.SendChat("§e" + e.Player.PlayerEntity.Name + " joined the game.");
            Log("§e" + e.Player.PlayerEntity.Name + " joined the game.");
        }

        static void Server_OnChat(object sender, ChatEventArgs e)
        {
            Log(e.RawText);
        }

        #endregion
    }
}
